package net.qiqbframework.config;

import net.qiqbframework.common.Registration;
import net.qiqbframework.lifecycle.Lifecycle;
import net.qiqbframework.lifecycle.LifecycleHandlerRegister;
import net.qiqbframework.lifecycle.Phase;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nonnull;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

import static net.qiqbframework.common.BuilderUtils.assertNonNull;


@Slf4j
public class MessageHandlerRegistrar implements Lifecycle {

    private final Supplier<Configuration> configurationSupplier;
    private final Function<Configuration, Object> messageHandlerBuilder;
    private final BiFunction<Configuration, Object, Registration> messageHandlerSubscriber;

    private Registration handlerRegistration;


    public MessageHandlerRegistrar(Supplier<Configuration> configSupplier,
                                   Function<Configuration, Object> messageHandlerBuilder,
                                   BiFunction<Configuration, Object, Registration> messageHandlerSubscriber) {
        this.configurationSupplier = configSupplier;
        this.messageHandlerBuilder = messageHandlerBuilder;
        this.messageHandlerSubscriber = messageHandlerSubscriber;
        this.handlerRegistration = null;
    }

    @Override
    public void registerLifecycleHandler(@Nonnull LifecycleHandlerRegister handle) {
        handle.onStart(Phase.LOCAL_MESSAGE_HANDLER_REGISTRATIONS, this::start);
        handle.onShutdown(Phase.LOCAL_MESSAGE_HANDLER_REGISTRATIONS, this::shutdown);
    }


    public void start() {
        Configuration config = configurationSupplier.get();
        Object annotatedHandler = messageHandlerBuilder.apply(config);
        assertNonNull(annotatedHandler, "AnnotatedMessageHandler may not be null");
        this.handlerRegistration = messageHandlerSubscriber.apply(config, annotatedHandler);
    }

    public void shutdown() {
        if (handlerRegistration == null) {
            log.info("Shutting down a message handler registrar before it was started.");
            return;
        }
        handlerRegistration.cancel();
    }

}
